package com.rrjjg.app.admin.bus;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rrjjg.app.admin.bus.bo.PlatformBo;
import com.rrjjg.app.admin.bus.bo.TreeBo;
import com.rrjjg.app.admin.data.service.IRoleProService;
import com.rrjjg.app.admin.data.service.IRoleService;
import com.rrjjg.app.admin.data.service.IUserService;
import com.rrjjg.app.admin.data.storage.entity.Role;
import com.rrjjg.app.admin.data.storage.entity.RolePro;
import com.rrjjg.app.admin.data.storage.po.PlatProPo;
import com.rrjjg.app.mybatis.bean.PageData;
import com.rrjjg.app.mybatis.util.PageUtil;
import lombok.val;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.rrjjg.app.admin.module.Constants.CONFIG_TOKEN_BODY_ROLE;
import static com.rrjjg.app.admin.module.Constants.CONFIG_TOKEN_BODY_ROLE_ID;

/**
 * ----------------------------------------------------------------------------- <br>
 * 功能 :  <br>
 * ----------------------------------------------------------------------------- <br>
 * 作者 : Vayne <br>
 * 时间 : 2023/4/18 <br>
 */
@Component
public class BRoleService {

    @Autowired
    IRoleService iRoleService;
    @Autowired
    IUserService iUserService;
    @Autowired
    IRoleProService iRoleProService;

    public PageData<Role> queryPage(Role role, int page, int size) {
        QueryWrapper queryWrapper = PageUtil.queryWrapper(role, Role.class);
        Page ans = iRoleService.page(new Page<>(page, size), queryWrapper);
        return PageUtil.EtoVList(ans);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean addRole(Role role, List<TreeBo> list) {
        boolean ans = iRoleService.save(role);
        if(ans){
            List<RolePro> rolePros = getRolePros(list, role.getId());
            ans = iRoleProService.saveBatch(rolePros);
        }
        return ans;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(Role role, List<TreeBo> list) {
        boolean ans = iRoleService.updateById(role);
        if(ans){
            LambdaQueryWrapper<RolePro> eq = Wrappers.<RolePro>lambdaQuery().eq(RolePro::getRoleId, role.getId());
            iRoleProService.remove(eq);
            List<RolePro> rolePros = getRolePros(list, role.getId());
            ans = iRoleProService.saveBatch(rolePros);
        }
        return ans;
    }
    @NotNull
    private List<RolePro> getRolePros(List<TreeBo> treeDto, Long roleId) {
        List<RolePro> rps = new ArrayList<>();
        treeDto = treeDto.stream().filter(p -> p.getPid() != 0).collect(Collectors.toList());
        for (TreeBo dto : treeDto) {
            RolePro rolePro = new RolePro();
            rolePro.setRoleId(roleId)
                    .setPId(dto.getPid())
                    .setPName(dto.getPlabel())
                    .setSCode(dto.getCode())
                    .setSId(dto.getId())
                    .setSName(dto.getLabel());
            rps.add(rolePro);
        }
        return rps;
    }


    private List<TreeBo> getTreeDto(List<PlatProPo> platProPos) {
        List<TreeBo> list = new ArrayList<>();
        if(!CollectionUtils.isEmpty(platProPos)){
            Map<Long, List<PlatProPo>> map = platProPos.stream().collect(Collectors.groupingBy(PlatProPo::getId));
            map.forEach((k,v)->{
                TreeBo treeDto = new TreeBo();
                List<TreeBo> children = new ArrayList<>();
                treeDto.setChildren(children);
                for (int i = 0; i < v.size(); i++) {
                    PlatProPo platProPo = v.get(i);
                    if(i == 0){
                        treeDto.setPid(0L);
                        treeDto.setPlabel("");
                        treeDto.setId(platProPo.getId());
                        treeDto.setLabel(platProPo.getName());
                    }
                    TreeBo ch = new TreeBo();
                    ch.setId(platProPo.getPid());
                    ch.setLabel(platProPo.getPname());
                    ch.setPid(treeDto.getId());
                    ch.setPlabel(treeDto.getLabel());
                    children.add(ch);
                }
                list.add(treeDto);
            });
        }
        return list;
    }


    @Transactional
    public boolean removeRole(Long roleId) {
        iRoleService.removeById(roleId);
        return iRoleProService.remove(Wrappers.<RolePro>lambdaQuery().eq(RolePro::getRoleId, roleId));
    }

    public List<Long> getProById(Long id) {
        List<Long> ans = new ArrayList<>();
        List<RolePro> list = iRoleProService.list(Wrappers.<RolePro>lambdaQuery().eq(RolePro::getRoleId, id));
        if(!CollectionUtils.isEmpty(list)){
            Map<Long, List<RolePro>> map = list.stream().collect(Collectors.groupingBy(RolePro::getPId));
            map.forEach((k,v)->{
                for (int i = 0; i < v.size(); i++) {
                    RolePro rolePro = v.get(i);
                    if(i == 0){
                        ans.add(rolePro.getPId());
                    }
                    ans.add(rolePro.getSId());
                }
            });
        }
        return ans;
    }


    public List<RolePro> services(){
        val wrapper = Wrappers.<RolePro>lambdaQuery()
                .eq(RolePro::getRoleId,iUserService.info().get(CONFIG_TOKEN_BODY_ROLE_ID))
                .gt(RolePro::getPId,0L);
        val list = iRoleProService.list(wrapper);
        return iRoleProService.list(wrapper);
    }

    public List<Role> list(){
        return iRoleService.list();
    }


    public IRoleService getiRoleService() {
        return iRoleService;
    }

    public IRoleProService getiRoleProService() {
        return iRoleProService;
    }

    public IUserService getiUserService() {
        return iUserService;
    }
}
